package scanpackage.outbound;



import io.netty.channel.ChannelHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import scanpackage.exception.AuthException;
import scanpackage.filter.HeaderHttpResponseFilter;
import scanpackage.filter.HttpRequestFilter;
import scanpackage.filter.HttpResponseFilter;
import scanpackage.future.CustomFutureCallback;
import scanpackage.generator.ResponseGenerator;
import io.micrometer.core.instrument.util.NamedThreadFactory;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpUtil;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;

import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import scanpackage.property.RouteProperty;
import scanpackage.router.HttpEndpointRouter;
import scanpackage.router.RandomHttpEndpointRouter;

import java.util.concurrent.*;
@Service
public class HttpOutboundHandler {


    private CloseableHttpAsyncClient httpclient;
    @Autowired
    private ExecutorService proxyService;
    @Autowired
    private RouteProperty routeProperty;
    @Autowired
    private HttpResponseFilter filter ;
    @Autowired
    private HttpEndpointRouter router ;
    @Autowired
    private CustomFutureCallback customFutureCallback;
    public HttpOutboundHandler() {
        int cores = Runtime.getRuntime().availableProcessors();


        IOReactorConfig ioConfig = IOReactorConfig.custom()
                .setConnectTimeout(1000)
                .setSoTimeout(1000)
                .setIoThreadCount(cores)
                .setRcvBufSize(32 * 1024)
                .build();

        httpclient = HttpAsyncClients.custom().setMaxConnTotal(40)
                .setMaxConnPerRoute(8)
                .setDefaultIOReactorConfig(ioConfig)
                .setKeepAliveStrategy((response, context) -> 6000)
                .build();
        httpclient.start();
    }
    public void handle(final FullHttpRequest fullRequest, final ChannelHandlerContext ctx,String backendUrl) {
        if("".equals(backendUrl))
            backendUrl=router.route(routeProperty,fullRequest.uri());
        //路由获取host
        final String url = backendUrl + fullRequest.uri();
        proxyService.submit(() -> fetchGet(fullRequest, ctx, url));
    }

    private void fetchGet(final FullHttpRequest inbound, final ChannelHandlerContext ctx, final String url) {
        final HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE);
        httpGet.setHeader("yourname", inbound.headers().get("yourname"));
        customFutureCallback.setCtx(ctx);
        customFutureCallback.setHttpGet(httpGet);
        customFutureCallback.setInbound(inbound);
        httpclient.execute(httpGet, customFutureCallback);
    }
}
